$.fn.extend({
    swiper: function (options) {
        var swipe = new Swiper(options, this)
        swipe.init()
    }
})

function Swiper(opts, wrap) {
    this.wrap = wrap; // 外层容器
    this.contents = opts.contents;  // 轮播内容     ****** 必填 ******
    this.toggle_time = opts.toggle_time || 2500;    // 切换时间
    this.type = opts.type || 'animate';    // 切换类型
    this.is_auto = opts.is_auto == undefined ? true : opts.is_auto;    // 是否自动切换
    this.show_toggle_btn = opts.show_toggle_btn || 'always';    // 是否显示切换按钮
    this.show_spots = opts.show_spots == undefined ? true : opts.show_spots;  // 是否显示小圆点
    this.spots_size = opts.spots_size || 10;    // 小圆点尺寸
    this.spots_position = opts.spots_position || 'center';  // 小圆点位置
    this.spots_color = opts.spots_color || '#ccc';  // 小圆点背景色
    this.cur_spot_color = opts.cur_spot_color || 'red'; // 当前小圆点颜色
    this.width = opts.width || wrap.width();
    this.height = opts.height || wrap.height();

    this.len = opts.contents.length;
    this.timer = null;
    this.lock = true;
    this.cur_index = 0;
}

Swiper.prototype.init = function () {
    this.create_dom()
    this.add_style()
    this.bind_event()
    if (this.is_auto) {
        this.auto_toggle()
    }
}

Swiper.prototype.create_dom = function () {
    var wrapper = $('<div class="swiper-wrapper"></div>')
    var items = $('<ul class="swiper-items"></ul>')
    var spots = $('<div class="swiper-spots"></div>')
    var left_btn = $('<button class="swiper-btn swiper-lbtn">&lt;</button>')
    var right_btn = $('<button class="swiper-btn swiper-rbtn">&gt;</button>')

    for (var i = 0; i < this.len; i++) {
        $('<li class="swiper-item"></li>').append(this.contents[i]).appendTo(items)
        $('<span></span>').appendTo(spots)
    }
    // 如果切换类型是动画，多加一个元素，以便无缝衔接
    if (this.type === 'animate') {
        $('<li class="swiper-item"></li>').append($(this.contents[0]).clone(true)).appendTo(items)
    }

    // 是否不显示小圆点
    if (!this.show_spots) {
        spots.hide()
    }

    if (this.show_toggle_btn === 'hide') {
        left_btn.hide()
        right_btn.hide()
    } else if (this.show_toggle_btn === 'hover') {
        wrapper.hover(function () {
            left_btn.css('opacity', 1)
            right_btn.css('opacity', 1)
        }, function () {
            left_btn.css('opacity', 0.2)
            right_btn.css('opacity', 0.2)
        })
    }

    // 所有元素依次添加到外层容器中
    wrapper.append(items).append(spots).append(left_btn).append(right_btn).appendTo(this.wrap)
}

Swiper.prototype.add_style = function () {
    // 设置内层容器宽高
    this.wrap.find('.swiper-wrapper').css({
        width: this.width,
        height: this.height
    }).find('.swiper-items').css({  // 设置 ul 宽高
        width: this.width * (this.wrap.find('.swiper-items li').length),
        height: this.height
    }).find('.swiper-item').css({
        width: this.width,
        height: this.height
    })
    // 设置内容宽高
    this.wrap.find('.swiper-item > *').css({
        width: '100%',
        height: '100%'
    })
    this.wrap.find('.swiper-spots').css('text-align', this.spots_position)
        .find('span').css({
            width: this.spots_size,
            height: this.spots_size,
            backgroundColor: this.spots_color
        }).eq(this.cur_index).css('background', this.cur_spot_color)
}

Swiper.prototype.bind_event = function () {
    var self = this;
    this.wrap.find('.swiper-lbtn').click(function () {
        if (!self.lock) return
        self.lock = false
        if (self.cur_index === 0) {
            self.cur_index = self.len
            if (self.type === 'animate') {
                self.wrap.find('.swiper-items').css('left', -self.width * self.len)
            }
        }
        self.cur_index--
        self.toggle_item()
    })

    this.wrap.find('.swiper-rbtn').click(function () {
        if (!self.lock) return
        self.lock = false
        if (self.cur_index === self.len) {
            self.cur_index = 0
            if (self.type === 'animate') {
                self.wrap.find('.swiper-items').css('left', 0)
            }
        }
        self.cur_index++
        self.toggle_item()
    })

    this.wrap.find('.swiper-spots span').click(function () {
        if (!self.lock) return
        self.lock = false
        self.cur_index = $(this).index()
        self.toggle_item()
    })

    // 如果是自动轮播的话，加上容器 hover 效果
    if (this.is_auto) {
        this.wrap.hover(function () {
            clearInterval(self.timer)
        }, this.auto_toggle.bind(this))          
        // 要用 bind 改变 this 指向，否则 this 就会指向 this.wrap
    }
}

// 切换效果
Swiper.prototype.toggle_item = function () {
    var self = this;
    var index = this.cur_index % this.len;
    if (this.type === 'animate') {
        this.wrap.find('.swiper-items').animate({
            left: -this.width * this.cur_index
        }, 700, function () { self.lock = true; })
    } else {
        if (this.type === 'fade') {
            this.wrap.find('.swiper-item').fadeOut().eq(index).fadeIn(700, function () { self.lock = true; })
        } else {
            this.wrap.find('.swiper-item').hide().eq(index).slideDown(700, function () { self.lock = true; })
        }
    }
    // animate 多了一个元素，索引 0 和 len 是同一个元素，所以用 索引 / len 表示正确索引
    this.wrap.find('.swiper-spots span')
        .css('backgroundColor', self.spots_color)
        .eq(index).css('backgroundColor', self.cur_spot_color)
}

// 自动切换
Swiper.prototype.auto_toggle = function(){
    var self = this
    clearInterval(this.timer)
    this.timer = setInterval(function(){
        self.wrap.find('.swiper-rbtn').trigger('click')
    }, this.toggle_time)
}